package com.zhida.userservice.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.zhida.common.context.UserContext;
import com.zhida.common.dto.UserDTO;
import com.zhida.common.entity.Result;
import com.zhida.common.utils.*;
import com.zhida.userservice.entity.User;
import com.zhida.userservice.entity.UserInfo;
import com.zhida.userservice.mapper.ResourcesMapper;
import com.zhida.userservice.mapper.UserInfoMapper;
import com.zhida.userservice.mapper.UserMapper;
import com.zhida.userservice.service.IUserService;
import jakarta.annotation.Resource;
import org.apache.commons.lang.StringUtils;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import static com.zhida.common.utils.StaticKeyUtil.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Your Name
 * @since 2024-07-15
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Resource
    UserMapper userMapper;
    @Resource
    UserInfoMapper userInfoMapper;
    @Resource
    RedisTemplate<String,Object> redisTemplate;
    @Resource
    ResourcesMapper resourcesMapper;

    @Override
    public Result<?> passwordLogin(UserDTO userDTO){
//        将user的password字段进行加密
        userDTO.setPassword(SaltMD5Util.generateSaltPassword(userDTO.getPassword()));
//        从数据库中查询是否存在这一条数据
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
//        根据用户名和密码查找用户id
        queryWrapper.allEq(Map.of("password",userDTO.getPassword(),"username",userDTO.getUsername()));
        User result = userMapper.selectOne(queryWrapper);
        if (result!=null){
            String token = TokenProcessor.createToken(userDTO.getUsername());
//            获取用户的账户信息
            HashMap<String,String> userInfo = userMapper.getUserInfo(userDTO.getUsername());
            userInfo.put("token",token);
            //  将登陆信息存入redis并设置7天过期
            try {
                redisTemplate.opsForValue().set(TOKEN_KEY + userDTO.getUsername(), ObjectUtil.Object2JsonStr(userInfo), TOKEN_EXPIRE_TIME , TimeUnit.DAYS );
            }catch (JsonProcessingException e){
                e.printStackTrace();
            }
            return Result.success(Map.of("token",token,"username",userDTO.getUsername()));
        }
        return Result.error("密码错误");
    }

    @Override
    public Result<?> codeLogin(UserDTO userDTO) {
        //  判断用户是否存在
        User result = userMapper.selectOne(new QueryWrapper<User>().eq("username",userDTO.getUsername()));
        if (result==null){
            return Result.error404("请先注册账户");
        }
        String code = Objects.requireNonNull(redisTemplate.opsForValue().get(CODE_KEY + userDTO.getUsername())).toString();
        if (!userDTO.getCode().equals(code)){
            return Result.error("验证码错误");
        }
        String token = TokenProcessor.createToken(userDTO.getUsername());
//            获取用户的账户信息
        HashMap<String,String> userInfo = userMapper.getUserInfo(userDTO.getUsername());
        userInfo.put("token",token);
        //  将登陆信息存入redis并设置7天过期
        try {
            redisTemplate.opsForValue().set(TOKEN_KEY + userDTO.getUsername(), ObjectUtil.Object2JsonStr(userInfo), TOKEN_EXPIRE_TIME , TimeUnit.DAYS );
        }catch (JsonProcessingException e){
            e.printStackTrace();
        }
        return Result.success(Map.of("token",token,"username",userDTO.getUsername()));
    }

    @Override
    public Result<?> register(UserDTO userDTO) {
//        判断用户绑定的手机号是否已经注册
        User result = userMapper.selectOne(new QueryWrapper<User>().eq("username",userDTO.getUsername()));
        if (result!=null){
            return Result.error("手机号已注册");
        }
        String code = Objects.requireNonNull(redisTemplate.opsForValue().get(CODE_KEY + userDTO.getUsername())).toString();
        if (!userDTO.getCode().equals(code)){
            return Result.error("验证码错误");
        }
//        插入一条 用户信息
        userDTO.setPassword(SaltMD5Util.generateSaltPassword(userDTO.getPassword()));
        userMapper.insert(new User(userDTO.getUsername(),userDTO.getPassword()));
//        查询当前用户的user_id
        UserInfo userInfo = new UserInfo();
        userInfo.setUsername(userDTO.getUsername());
        userInfoMapper.insert(userInfo);
        System.out.println(userInfo);
        return Result.successMsg("注册成功");
    }

    @Override
    public Result<?> updateUserInfo(User user) {
        UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();
        if (StringUtils.isNotBlank(user.getNickname())){
            userUpdateWrapper.set("nickname",user.getNickname());
        }
        if (StringUtils.isNotBlank(user.getHeader())){
//            持久化
            String base64 = user.getHeader();
            String fileName = FileUtil.saveFile(FileUtil.base642File(base64), CURRENT_PATH + "/" + USER_HEADER_IMAGE_UPLOAD_DIR,FileUtil.getBase64FileSuf(base64));
//            将文件绝对地址插入resource表
            resourcesMapper.insertFilePath(UserContext.getUser(),USER_HEADER_IMAGE_UPLOAD_DIR, fileName);
            user.setHeader(fileName);
            userUpdateWrapper.set("header",fileName);
        }
        if (StringUtils.isNotBlank(user.getEmail())){
            userUpdateWrapper.set("email",user.getEmail());
        }
        if (StringUtils.isNotBlank(user.getPhone())){
            userUpdateWrapper.set("phone",user.getPhone());
        }
        userUpdateWrapper.eq("username", UserContext.getUser());
        int update_flag = userMapper.update(userUpdateWrapper);
        if (update_flag == 0){
            return Result.error("用户信息更新失败");
        } else {
            return Result.successMsg("更新成功");
        }
    }

    @Override
    public Result<?> getUserInfo() throws JsonProcessingException {
        QueryWrapper<User> queryWrapper = new QueryWrapper<User>().eq("username", UserContext.getUser());
        queryWrapper.select("username","vip_status","create_time","header","financial","emotional","skill","nickname","email","phone");
        Map<String, Object> userMap = userMapper.selectMaps(queryWrapper).get(0);
        return Result.success(userMap);
    }

    @Override
    public Result<?> sendCode(String username) {
        try {
            if (StringUtils.isNotBlank(username)){
                //  生成，并发送验证码
                String code = CodeUtil.generateCode(username);
                //  将验证码存入redis,并设置15分钟有效期
                redisTemplate.opsForValue().set(CODE_KEY + username,code,15,TimeUnit.MINUTES);
                return Result.successMsg("发送成功");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return Result.error("服务器异常，短信发送失败。");
    }

}
